# Create your views here.
from base64 import urlsafe_b64decode
import logging
from django.shortcuts import render_to_response
from django.template import Context
from django.template.context import RequestContext
from django.utils import simplejson as json
from django.views.decorators.csrf import csrf_exempt
from friendmap.facebook.utils import FTManagement, ConfMng, getJSONFormatFromFriends
from friendmap.lib import facebook
from google.appengine.runtime import apiproxy_errors
from google.appengine.api import urlfetch_errors
from friendmap.facebook.models import User

# Get the page with the facebook login

def fb_login(request):
    config = ConfMng().get_default_config()
    pageParams = {'appId': config.get('DEFAULT','appId'), 'perms': config.get('DEFAULT','perms')}
    return render_to_response('fb_login.html', Context(pageParams),
                              context_instance=RequestContext(request))

def friends_map(request,friends):
    localizedFriends,unlocalizedFriends = getJSONFormatFromFriends(friends)
    return render_to_response('fb_friends_map.html',
            {'locations' : json.dumps(localizedFriends,ensure_ascii=False),
             'unlocalized' : json.dumps(unlocalizedFriends,ensure_ascii=False)})

#TODO: code legibility: rename this
def fb_site_login(request):
    if 'userID' not in request.POST:
        return fb_login(request)

    userID = request.POST['userID']
    accessToken = request.POST['accessToken']
    logging.debug("Got the userId and the access token")
    return get_friends(request,userID,accessToken)

def get_friends(request,userID,accessToken):
    # check if the user is in the DB, if not add him
    graph = facebook.GraphAPI(accessToken)
    user = User.get_by_key_name(userID)
    if not user:
        profile = None
        try:
            profile = graph.get_object(userID)
        except (apiproxy_errors.DeadlineExceededError, urlfetch_errors.DeadlineExceededError):
            try:
                profile = graph.get_object(userID)
            except (apiproxy_errors.DeadlineExceededError, urlfetch_errors.DeadlineExceededError):
                return render_to_response('error.html',{'message':'The request took too long to execute. Please try again later'})
        user = User(key_name=str(userID),
                    id=str(userID),
                    name=profile["name"],
                    profile_url=profile["link"],
                    access_token=accessToken)
        user.put()

    elif user.access_token != accessToken:
        user.access_token = accessToken
        user.put()
    friends = graph.get_connections(userID,'friends',fields='name,location')
    return friends_map(request,friends)

def fb_fusion_tables(request,userID,friends):
    # store in fusion table
    friendsManagement = FTManagement()
    (tableId,noLocation) = friendsManagement.store_friends(userID,friends)
    if tableId == -1:
        return render_to_response('error.html',{'message':"An unexpected error has occured! Please try again later "})
    # redirect the use to this page
    if noLocation is None: noLocation = list()
    return render_to_response('fb_friends.html',{'tableId':tableId, 'userId':userID, 'privateLocationFriends': ', '.join(noLocation)})

def error_404_handler(request):
    logging.warn("404 occured for page %s" % request.get_full_path())
    return fb_login(request)

@csrf_exempt
def facebook_app(request):
    logging.debug("called facebook app")

    if 'error_reason' in request.GET:
        if request.GET['error_reason'] == 'user_denied':
            return render_to_response('error.html',{'message':"You denied the needed permissions to display your friends. " +
                                                    "If it is reasuring, we won't store any data from you, and you can always revoke Friends Map' permissions from Apps tab in Facebook."})
    if 'signed_request' not in request.POST:
        logging.debug("Can't find signed_request in POST params")
        return fb_login(request)

    jsonObj = None
    try:
        signed_request = request.POST['signed_request']
        logging.debug('signed_request:' + str(signed_request))
        jsonObj = json.loads(urlsafe_b64decode(str(signed_request).split('.')[1] + '========'))
    except Exception, e:
        logging.warn("An error occured while parsing the signed request: %s " % e.message)
        return facebook_authenticate(request)

    logging.debug("signed_request loaded")
    if 'user_id' not in jsonObj:
        return facebook_authenticate(request)

    userID = jsonObj['user_id']
    accessToken = jsonObj['oauth_token']
    if userID is None or accessToken is None:
        return render_to_response('error.html',{'message':"Authentication with Facebook failed ! Please try again later "})

    return get_friends(request,userID,accessToken)

def facebook_authenticate(request):
    logging.debug("called facebook authenticate")
    config = ConfMng().get_default_config()
    url = config.get('AUTH','usr_authentication_link') + config.get('AUTH','usr_authentication_params')
    logging.debug("redirecting to: %s" % url)
    return render_to_response('fb_authenticate.html',{ 'url' : url })


